package com.gomyb.redis.config;

import com.gomyb.redis.annotation.Message;
import com.gomyb.redis.message.MessageConsumerAbstract;
import com.gomyb.redis.RedisService;
import com.gomyb.redis.task.ThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author <a href="mailto:hellohesir@gmail.com">Mr_He</a>
 * 2019/6/14 14:11
 */
@Component
@Slf4j
@Lazy(true)
public class AnnotationScannerConfigurer implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Autowired
    private RedisService redisService;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof MessageConsumerAbstract) {
            Class<?> clazz = bean.getClass();
            Message message = clazz.getAnnotation(Message.class);
            try {
                Field field = clazz.getField("redisService");
                field.set(bean, redisService);

                Field field1 = clazz.getField("channels");
                field1.set(bean, message.value());

                Method method = clazz.getMethod("invoke");
                ThreadPool.exe(() -> {
                    try {
                        method.invoke(bean);
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                        log.error("消息订阅失败", e);
                    }
                });
            } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return bean;
    }
}
